﻿using TrueSync;
using UnityEngine;

namespace HEFramework
{
    public static class ATKEffectSystem
    {
        [EntitySystem]
        public class ATKEffectAwakeSystem : AwakeSystem<ATKEffect>
        {
            protected override void Awake(ATKEffect _self)
            {
                _self.AddChild<TransformComponent>();
                _self.AddChild<MoveComponent>();
            }
        }

        [EntitySystem]
        public class ATKEffectUpdateSystem : UpdateSystem<ATKEffect>
        {
            protected override void Update(ATKEffect _self)
            {
                if (_self.WaitDisappear())
                {
                    return;
                }

                switch (_self.Data.Type)
                {
                    case (int)eATKEffectType.Track:

                        //就是双方死亡了，攻击效果一样能继续执行
                        var a = _self.A.Entity;
                        var b = _self.B.Entity;

                        var acA = a?.GetChild<AttributeComponent>();
                        var acB = b?.GetChild<AttributeComponent>();
                        var tcB = b?.GetChild<TransformComponent>();

                        if (acA != null)
                        {
                            _self.Value = acA.P_ATK.Value;
                        }

                        if (acB != null && tcB != null)
                        {
                            TSVector p = tcB.GetCenterPos(acB);
                            _self.Target = p;
                        }

                        var tc = _self.GetChild<TransformComponent>();
                        if (TSVector.Distance(tc.P, _self.Target) < 0.1)
                        {
                            //追踪对象未被销毁
                            if (acB != null)
                            {
                                if (acA != null)
                                {
                                    acB.OnDamage(acA, acA.P_ATK.Value, ePowerType.Physics, true);
                                }
                                else
                                {
                                    acB.OnDamage(null, _self.Value, ePowerType.Physics, true);
                                }
                            }

                            _self.Disappear();
                        }
                        else
                        {
                            _self.GetChild<MoveComponent>().SetTarget(tc.P, _self.Target, _self.Data.Speed);
                        }

                        break;
                }
            }
        }

        [EntitySystem]
        public class ATKEffectDestroySystem : DestroySystem<ATKEffect>
        {
            protected override void Destroy(ATKEffect _self)
            {
                _self.Data = null;
                _self.A = null;
                _self.B = null;
            }
        }

        public static void Execute(this ATKEffect _self, Entity _a, Entity _b)
        {
            var acA = _a.GetChild<AttributeComponent>();
            var acB = _b.GetChild<AttributeComponent>();
            var tcA = _a.GetChild<TransformComponent>();
            var tcB = _b.GetChild<TransformComponent>();
            var tc = _self.GetChild<TransformComponent>();
            var dc = _self.GetSceneChild<DataTableComponent>();
            if (acA == null || acB == null || tcA == null || tcB == null || tc == null || dc == null)
            {
                return;
            }

            _self.A = _a;
            _self.B = _b;

            int id = acA.Attribute.P_ATK_E;
            _self.Data = dc.LoadDataTable<DRATKEffect>().GetData(id);
            if (_self.Data == null)
            {
                _self.Dispose();
                return;
            }


            switch (_self.Data.Type)
            {
                case (int)eATKEffectType.Point:
                {
                    TSVector pB = tcB.GetCenterPos(acB);
                    tc.P = pB;
                    _self.AddChild<ATKEffectView, int, TSVector>(id, pB);
                    acB.OnDamage(acA, acA.P_ATK.Value, ePowerType.Physics, true);
                    _self.Dispose();
                    break;
                }

                case (int)eATKEffectType.Track:
                {
                    TSVector pA = tcA.GetCenterPos(acA);
                    TSVector pB = tcB.GetCenterPos(acB);
                    _self.Target = pB;
                    TSVector dis = pB - pA;
                    dis = dis.normalized;
                    TSVector p = pA + Formula.LG(acA.Attribute.B_RAG) * dis;
                    tc.P = p;
                    _self.AddChild<ATKEffectView, int, TSVector>(id, p);
                }

                    break;
            }
        }

        private static void Disappear(this ATKEffect _self)
        {
            var dc = _self.GetSceneChild<DataTableComponent>();

            if (dc == null)
            {
                _self.Dispose();
                return;
            }

            var data = dc.LoadDataTable<DRATKEffect>().GetData(_self.Data.ID);
            _self.Disappear = 1;
            _self.Disappear_Time = Formula.TM(data.DieOutTime);
        }

        private static bool WaitDisappear(this ATKEffect _self)
        {
            if (_self.Disappear == 1)
            {
                FP deltaTime = Time.deltaTime;

                _self.Disappear_Time -= deltaTime;

                if (_self.Disappear_Time <= 0)
                {
                    _self.Dispose();
                }

                return true;
            }

            return false;
        }
    }
}